package com.blm.handler;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class UserDeserializer extends JsonDeserializer<User> {
    @Override
    public User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        // example json
        // ["org.springframework.security.core.userdetails.User",{"password":"$2a$10$KdDkGThGCEXpfTAYugLMpuAwIU/4eg0cqtlUOSj1QZBLVvGNzgv8u","username":"merchant1","authorities":["java.util.Collections$UnmodifiableSet",[["org.springframework.security.core.authority.SimpleGrantedAuthority",{"authority":"ROLE_MERCHANT"}]]],"accountNonExpired":true,"accountNonLocked":true,"credentialsNonExpired":true,"enabled":true}]
        JsonNode node = p.getCodec().readTree(p);

        // Safely get text values with defaults
        String username = getTextOrDefault(node, "username", "");
        String password = getTextOrDefault(node, "password", "");

        // Extract authorities safely
        List<GrantedAuthority> authorities = new ArrayList<>();
        JsonNode authoritiesOuterArray = node.get("authorities");
        if (authoritiesOuterArray != null && authoritiesOuterArray.isArray() && authoritiesOuterArray.size() > 1) {
            JsonNode authoritiesListWrapper = authoritiesOuterArray.get(1); // This should be the array like [["org.springframework.security.core.authority.SimpleGrantedAuthority",{"authority":"ROLE_MERCHANT"}]]
            if (authoritiesListWrapper != null && authoritiesListWrapper.isArray()) {
                for (JsonNode authorityEntryArray : authoritiesListWrapper) { // authorityEntryArray is like ["org.springframework.security.core.authority.SimpleGrantedAuthority",{"authority":"ROLE_MERCHANT"}]
                    if (authorityEntryArray != null && authorityEntryArray.isArray() && authorityEntryArray.size() > 1) {
                        JsonNode authorityDetailsObject = authorityEntryArray.get(1); // This is the object like {"authority":"ROLE_MERCHANT"}
                        if (authorityDetailsObject != null && authorityDetailsObject.isObject()) {
                            JsonNode authorityNode = authorityDetailsObject.get("authority");
                            if (authorityNode != null && authorityNode.isTextual()) {
                                authorities.add(new SimpleGrantedAuthority(authorityNode.asText()));
                            }
                        }
                    }
                }
            }
        }

        // Get boolean values safely
        boolean enabled = getBooleanOrDefault(node, "enabled", true);
        boolean accountNonExpired = getBooleanOrDefault(node, "accountNonExpired", true);
        boolean credentialsNonExpired = getBooleanOrDefault(node, "credentialsNonExpired", true);
        boolean accountNonLocked = getBooleanOrDefault(node, "accountNonLocked", true);

        return new User(username, password, enabled, accountNonExpired,
                credentialsNonExpired, accountNonLocked, authorities);
    }

    private String getTextOrDefault(JsonNode node, String fieldName, String defaultValue) {
        JsonNode valueNode = node.get(fieldName);
        return valueNode != null ? valueNode.asText() : defaultValue;
    }

    private boolean getBooleanOrDefault(JsonNode node, String fieldName, boolean defaultValue) {
        JsonNode valueNode = node.get(fieldName);
        return valueNode != null ? valueNode.asBoolean() : defaultValue;
    }
}
